<template>
  <lay-container fluid="true" class="option-box">
    <!-- search -->
    <lay-card>
      <lay-form style="margin-top: 10px">
        <lay-row>
          <lay-col :md="5">
            <lay-form-item label="用户">
              <lay-input v-model="searchQuery.userName" placeholder="请输入"
                size="sm" :allow-clear="true" ></lay-input>
            </lay-form-item>
          </lay-col>
          <lay-col :md="5">
            <lay-form-item label="接口">
              <lay-input v-model="searchQuery.apiName" placeholder="请输入"
                size="sm" :allow-clear="true" ></lay-input>
            </lay-form-item>
          </lay-col>
          <lay-col :md="9">
            <lay-form-item label="记录时间" label-width="80">
              <lay-date-picker size="sm" v-model="searchRangeTime" range type="datetime" abort="" 
                :placeholder="['开始', '结束']"></lay-date-picker>
            </lay-form-item>
          </lay-col>
          <lay-col :md="5">
            <lay-form-item label-width="20">
              <lay-button style="margin-left: 20px" type="normal" size="sm" @click="toSearch">
                查询
              </lay-button>
              <lay-button size="sm" @click="toReset"> 重置 </lay-button>
            </lay-form-item>
          </lay-col>
        </lay-row>
      </lay-form>
    </lay-card>
    <!-- table -->
    <div class="table-box">
      <lay-table :page="searchPage" :height="'100%'" :columns="columns" :loading="loading" :default-toolbar="true"
        :data-source="dataSource" @change="toSearch" @sortChange="sortChange">
        <template #costTime="{ row }">
          <div class="oneRow">{{ (row.costTime*0.001).toFixed(2) }} s</div>
        </template>
        <template v-slot:operator="{ row }">
          <lay-button size="xs" border="green" border-style="dashed" @click="showDetail(row)">详情</lay-button>
        </template>
      </lay-table>
    </div>
    <!-- layer -->
    <lay-layer v-model="visible" title="详情" :area="['700px', '460px']">
        <div style="padding: 20px">
          <lay-row>
            <lay-col md="4" class="title">操作人 </lay-col>
            <lay-col md="13" class="content"> {{ dataLayer.userName + '(' + dataLayer.userToken + ')' }}</lay-col>
            <lay-col md="3" class="title">IP地址</lay-col>
            <lay-col md="4" class="content borderR">{{ dataLayer.userIp }}</lay-col>
          </lay-row>
          <lay-row>
            <lay-col md="4" class="title" style="height: 59px;">操作人 Agent</lay-col>
            <lay-col md="20" class="content"
              style="height: 59px; padding-top: 5px; white-space: pre-line;
              line-height: 24px; padding-top: 5px; border-right: 1px solid #e8e8e8;">
              {{ dataLayer.userAgent }}
            </lay-col>
          </lay-row>
          <lay-row>
            <lay-col md="4" class="title">操作时间</lay-col>
            <lay-col md="8" class="content">{{ dataLayer.createDate }}</lay-col>
            <lay-col md="4" class="title">请求耗时</lay-col>
            <lay-col md="8" class="content borderR">{{ dataLayer.costTime }}s</lay-col>
          </lay-row>
          <lay-row>
            <lay-col md="4" class="title">请求方式</lay-col>
            <lay-col md="4" class="content">{{ dataLayer.apiMethod }}</lay-col>
            <lay-col md="4" class="title">请求地址</lay-col>
            <lay-col md="12" class="content borderR">{{ dataLayer.apiPath }}</lay-col>
          </lay-row>
          <lay-row>
            <lay-col md="4" class="title" style="height: 60px;">请求 参数</lay-col>
            <lay-col md="20" class="content"
              style="height: 60px; padding-top: 5px; white-space: pre-line;
              line-height: 24px; padding-top: 5px; border-right: 1px solid #e8e8e8;">
              {{ dataLayer.reqBody }}
            </lay-col>
          </lay-row>
          <lay-row>
            <lay-col md="4" class="title borderB" style="height: 130px;">返回结果</lay-col>
            <lay-col md="20" class="content"
              style="height: 130px; padding-top: 5px; white-space: pre-line; overflow: auto;
              line-height: 24px; padding-top: 5px; border-right: 1px solid #e8e8e8;">
              {{ dataLayer.resBody }}
            </lay-col>
          </lay-row>
        </div>
      </lay-layer>
  </lay-container>
</template>

<script setup lang="ts">
  import { ref, reactive } from 'vue'
  import { layer } from '@layui/layui-vue'
  
  import { logList } from '../../../api/module/system'
  
  // 其他
  // -- 加载中
  const loading = ref(false);
  // -- 是否可见
  const visible = ref(false)
  // -- 查询
  const searchRangeTime = ref([]);
  const searchQuery = ref({
    apiName: undefined, userName: undefined,
    startTime: '2024-04-01 01:01:00', endTime: '2099-01-1 01:01:00',
    current: 1, limit: 15,
    orderProperty: undefined, orderSort: 0
  });
  const searchPage = reactive({ 
    current: 1, limit: 15, total: 100 , limits: [15,30,45,60]
  });
  // -- 数据源
  const dataSource = ref([]);
  // -- 表结构
  const columns = ref([
    { title: '操作人 名', width: '80', key: 'userName' },
    { title: '操作人 地址', width: '120', key: 'userIp' },
    { title: '接口 类型', width: '80', key: 'apiMethod', align: 'center' },
    { title: '接口 耗时', width: '80', key: 'costTime', align: 'center', customSlot: 'costTime' },
    { title: '接口 名', width: '120', key: 'apiName' },
    { title: '接口 路径', key: 'apiPath' },
    { title: '调用 时间', key: 'createDate' },
    {
      title: '操作', width: '100px', customSlot: 'operator',
      fixed: 'right'
    }
  ]);
  // -- 明细数据
  const dataLayer = ref({
      "apiName": "",
      "apiPath": "",
      "apiMethod": "",
      "costTime": 0,
      "createDate": "",
      "userAgent": "",
      "userIp": "",
      "userToken": "",
      "userName": "",
      "reqBody": "{}",
      "resBody": "{}"  ,
  })
  
  // -- 方法函数
  // 加载默认数据
  function loadDataSource(){
    loading.value = true;
    logList(searchQuery.value).then(({ data, code, msg }) => {
      if (code == 200) {
        searchPage.total = data.total;
        dataSource.value = data.list;
      }
      loading.value = false;
    })
  }
  // 搜索
  function toSearch(page : any) {
    searchQuery.value.current = searchPage.current;
    searchQuery.value.limit = searchPage.limit;
    searchQuery.value.startTime = searchRangeTime.value[0];
    searchQuery.value.endTime = searchRangeTime.value[1];

    loadDataSource();
  }
  // 搜索 sort
  function sortChange(key : any, sort : number){
    searchQuery.value.orderProperty = key;
    searchQuery.value.orderSort = sort
  }
  //
  function toReset() {
    searchQuery.value = {
      apiName: undefined, userName: undefined,
      startTime: '2024-04-01 01:01:00', endTime: '2099-01-1 01:01:00',
      current: 1, limit: 15,
      orderProperty: undefined, orderSort: 0
    }
  }
  function showDetail(row : any) {
    visible.value = true
    dataLayer.value = row
  }
  
  // --预执行
  loadDataSource();
</script>

<style scoped>
  .option-box {
    height: calc(100vh - 110px);
    margin-top: 10px; box-sizing: border-box; 
  }

  .top-search { margin-top: 10px; padding: 10px; height: 40px; border-radius: 4px; background-color: #fff; }
  
  .table-box { margin-top: 10px; padding: 10px; height: 730px; width: 100%; border-radius: 4px; box-sizing: border-box; background-color: #fff; }

  .search-input {
    display: inline-block;
    width: 98%;
    margin-right: 10px;
  }

  .table-style {
    margin-top: 10px;
  }

  .isChecked {
    display: inline-block;
    background-color: #e8f1ff;
    color: red;
  }

  .oneRow {
    width: 180px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    text-align: left;
  }

  .title {
    height: 40px;
    line-height: 40px;
    padding: 0 10px;
    display: inline-block;
    background: #f7f7f7;
    border-top: 1px solid #e8e8e8;
    border-left: 1px solid #e8e8e8;
  }

  .content {
    height: 40px; line-height: 40px; padding: 0 3px 0 10px; border-top: 1px solid #e8e8e8; border-left: 1px solid #e8e8e8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; text-align: left;
  }

  .borderR {
    border-right: 1px solid #e8e8e8;
  }

  .borderB {
    border-bottom: 1px solid #e8e8e8;
  }
</style>